package net.scribblemedia.candle.util;

import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public final class ScribbleCollectionUtils {

	private static final String COMMA = ",";

	private ScribbleCollectionUtils() {}

	public static <T> List<T> asList(T... elements) {
		List<T> list = new ArrayList<T>();
		for (T element : elements) {
			list.add(element);
		}
		return list;
	}
	
	public static <T> Set<T> asSet(T... elements) {
		return new HashSet<T>(asList(elements));
	}

	public static <K> Map<K, Object> singleElementMap(K key, Object value) {
		Map<K, Object> map = new HashMap<K, Object>();
		map.put(key, value);
		return map;
	}

	public static boolean containsEmptyElements(Collection<String> values) {
		for (String val : values) {
			if (isEmpty(val)) {
				return true;
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> singleElementList(T value) {
		return asList(value);
	}

	public static <T> T lastElement(Collection<T> collection) {
		return lastElement(new ArrayList<T>(collection));
	}
	
	public static <T> T lastElement(List<T> list) {
		if (list == null) {
			return null;
		}
		
		if (list.isEmpty()) {
			return null;
		}
		
		return list.get(list.size() - 1);
	}
	
	public static <T> T firstElement(Collection<T> collection) {
		if (collection == null) {
			return null;
		}
		
		if (collection.isEmpty()) {
			return null;
		}

		return collection.iterator().next();
	}	
	
	@SuppressWarnings("rawtypes")
	public static Collection<String> objectCollectionToStringCollection(Collection objectCollecion) {
		List<String> strings = new ArrayList<String>();
		for (Object object : objectCollecion) {
			strings.add(object.toString());
		}
		return strings;
	}
	
	public static void appendToStringMap(Map<String, String> map, String key, String valueToAppend, String delimiter) {
		String currentValue = map.get(key);
		
		if (currentValue == null) {
			currentValue = "";
		} else {
			currentValue = currentValue + delimiter;
		}
		
		map.put(key, currentValue + valueToAppend);
	}
	
	public static void appendToStringMap(Map<String, String> map, String key, String value) {
		appendToStringMap(map, key, value, COMMA);
	}
	
	public static String toCommaDelimitedString(Collection<String> stringsToDelimit) {
		return toDelimitedString(stringsToDelimit, COMMA);
	}
	
	public static String toDelimitedString(Collection<String> stringsToDelimit, String delimiter) {
		StringBuffer buf = new StringBuffer();
		int index = 0;
		for (String string : stringsToDelimit) {
			buf.append(string);
			
			index++;
			
			if (index < stringsToDelimit.size()) {
				buf.append(delimiter);
			}
		}
		return buf.toString();
	}
	
	public static Set<String> commaDelimitedStringToSet(String commaDelimitedString) {
		return new HashSet<String>(commaDelimitedStringToList(commaDelimitedString));
	}
	
	public static List<String> commaDelimitedStringToList(String commaDelimitedString) {
		List<String> list = new ArrayList<String>();
		if (isNotBlank(commaDelimitedString)) {
			String[] splitArray = commaDelimitedString.split(COMMA);
			for (String element : splitArray) {
				String trimmedElement = element.trim();
				list.add(trimmedElement);
			}
		}
		return list;
	}
	
	public static boolean hasElements(Collection<?> collection) {
		if (collection == null) {
			return false;
		}
		
		return !collection.isEmpty();
	}
}
